﻿// -----------------------------------------------------------------------
// <copyright file="SettingsManager.cs" company="Microsoft">
//  Hmmm?
// </copyright>
// -----------------------------------------------------------------------

namespace StatePersistence.Implementation
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Xml;
    using Interface;

    /// <summary>
    /// Manages settings storage and retrieval of a generic type of settings object
    /// </summary>
    /// <typeparam name="T">The type storing the data</typeparam>
    public class SettingsManager<T> : ISettingsManager<T> where T : ICanManageThisType
    {
        /// <summary>
        /// the name of the calling application
        /// </summary>
        private readonly string applicationName;

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsManager&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="applicationName">Name of the application.</param>
        public SettingsManager(string applicationName)
        {
            this.applicationName = applicationName;
        }

        /// <summary>
        /// Gets the max settings number.
        /// </summary>
        public int MaxSettingsNumber
        {
            get
            {
                var jobs = this.ListStoredSettings().ToArray();
                int maxSettingsNumber = 0;
                if (jobs.Any())
                {
                    maxSettingsNumber = jobs.Max(j => j.Number);
                }

                return maxSettingsNumber;
            }
        }

        /// <summary>
        /// Gets the temp folder.
        /// </summary>
        private string TempFolder
        {
            get
            {
                string localApplicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                string specificApplicationDataFolder = Path.Combine(localApplicationDataFolder, this.applicationName);
                if (!Directory.Exists(specificApplicationDataFolder))
                {
                    Directory.CreateDirectory(specificApplicationDataFolder);
                }

                return specificApplicationDataFolder;
            }
        }

        /// <summary>
        /// Stores the specified settings.
        /// </summary>
        /// <param name="settings">The settings.</param>
        public void Store(T settings)
        {
            string fileName = string.IsNullOrWhiteSpace(settings.Name) ? Path.Combine(this.TempFolder, string.Format("{0}.xml", settings.Number)) : Path.Combine(this.TempFolder, string.Format("{0}.xml", settings.Name));
            var xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(XmlSerializationHelper.Serialize(settings));
            xmlDocument.Save(fileName);
        }

        /// <summary>
        /// Lists the stored settings.
        /// </summary>
        /// <returns>An IEnumerable of type T holding the stored state data</returns>
        public IEnumerable<T> ListStoredSettings()
        {
            var files = Directory.GetFiles(this.TempFolder, "*.xml");
            return files.Select(XmlSerializationHelper.DeserializeXmlFile<T>);
        }

        /// <summary>
        /// Clears the stored settings.
        /// </summary>
        public void ClearStoredSettings()
        {
            foreach (var file in Directory.GetFiles(this.TempFolder))
            {
                File.Delete(file);
            }
        }
    }
}
